﻿using Crux.Core.SQL.Formatter.Core;

namespace Crux.Core.SQL.Formatter.Language;
/// <summary>
/// 
/// </summary>
public class N1qlFormatter : AbstractFormatter
{
    private readonly static List<string> ReservedWords = new List<string>{
        "ALL",
        "ALTER",
        "ANALYZE",
        "AND",
        "ANY",
        "ARRAY",
        "AS",
        "ASC",
        "BEGIN",
        "BETWEEN",
        "BINARY",
        "BOOLEAN",
        "BREAK",
        "BUCKET",
        "BUILD",
        "BY",
        "CALL",
        "CASE",
        "CAST",
        "CLUSTER",
        "COLLATE",
        "COLLECTION",
        "COMMIT",
        "CONNECT",
        "CONTINUE",
        "CORRELATE",
        "COVER",
        "CREATE",
        "DATABASE",
        "DATASET",
        "DATASTORE",
        "DECLARE",
        "DECREMENT",
        "DELETE",
        "DERIVED",
        "DESC",
        "DESCRIBE",
        "DISTINCT",
        "DO",
        "DROP",
        "EACH",
        "ELEMENT",
        "ELSE",
        "END",
        "EVERY",
        "EXCEPT",
        "EXCLUDE",
        "EXECUTE",
        "EXISTS",
        "EXPLAIN",
        "FALSE",
        "FETCH",
        "FIRST",
        "FLATTEN",
        "FOR",
        "FORCE",
        "FROM",
        "FUNCTION",
        "GRANT",
        "GROUP",
        "GSI",
        "HAVING",
        "IF",
        "IGNORE",
        "ILIKE",
        "IN",
        "INCLUDE",
        "INCREMENT",
        "INDEX",
        "INFER",
        "INLINE",
        "INNER",
        "INSERT",
        "INTERSECT",
        "INTO",
        "IS",
        "JOIN",
        "KEY",
        "KEYS",
        "KEYSPACE",
        "KNOWN",
        "LAST",
        "LEFT",
        "LET",
        "LETTING",
        "LIKE",
        "LIMIT",
        "LSM",
        "MAP",
        "MAPPING",
        "MATCHED",
        "MATERIALIZED",
        "MERGE",
        "MISSING",
        "NAMESPACE",
        "NEST",
        "NOT",
        "NULL",
        "NUMBER",
        "OBJECT",
        "OFFSET",
        "ON",
        "OPTION",
        "OR",
        "ORDER",
        "OUTER",
        "OVER",
        "PARSE",
        "PARTITION",
        "PASSWORD",
        "PATH",
        "POOL",
        "PREPARE",
        "PRIMARY",
        "PRIVATE",
        "PRIVILEGE",
        "PROCEDURE",
        "public",
        "RAW",
        "REALM",
        "REDUCE",
        "RENAME",
        "RETURN",
        "RETURNING",
        "REVOKE",
        "RIGHT",
        "ROLE",
        "ROLLBACK",
        "SATISFIES",
        "SCHEMA",
        "SELECT",
        "SELF",
        "SEMI",
        "SET",
        "SHOW",
        "SOME",
        "START",
        "STATISTICS",
        "STRING",
        "SYSTEM",
        "THEN",
        "TO",
        "TRANSACTION",
        "TRIGGER",
        "TRUE",
        "TRUNCATE",
        "UNDER",
        "UNION",
        "UNIQUE",
        "UNKNOWN",
        "UNNEST",
        "UNSET",
        "UPDATE",
        "UPSERT",
        "USE",
        "USER",
        "USING",
        "VALIDATE",
        "VALUE",
        "VALUED",
        "VALUES",
        "VIA",
        "VIEW",
        "WHEN",
        "WHERE",
        "WHILE",
        "WITH",
        "WITHIN",
        "WORK",
        "XOR"
    };

    private readonly static List<string> ReservedTopLevelWords = new List<string>{
        "DELETE FROM",
        "EXCEPT ALL",
        "EXCEPT",
        "EXPLAIN DELETE FROM",
        "EXPLAIN UPDATE",
        "EXPLAIN UPSERT",
        "FROM",
        "GROUP BY",
        "HAVING",
        "INFER",
        "INSERT INTO",
        "LET",
        "LIMIT",
        "MERGE",
        "NEST",
        "ORDER BY",
        "PREPARE",
        "SELECT",
        "SET CURRENT SCHEMA",
        "SET SCHEMA",
        "SET",
        "UNNEST",
        "UPDATE",
        "UPSERT",
        "USE KEYS",
        "VALUES",
        "WHERE"
    };

    private readonly static List<string> ReservedTopLevelWordsNoIndent = new List<string> { "INTERSECT", "INTERSECT ALL", "MINUS", "UNION", "UNION ALL" };

    private readonly static List<string> ReservedNewlineWords = new List<string>{
        "AND",
        "OR",
        "XOR",
        "JOIN",
        "INNER JOIN",
        "LEFT JOIN",
        "LEFT OUTER JOIN",
        "RIGHT JOIN",
        "RIGHT OUTER JOIN"
    };
    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public override DialectConfig DoDialectConfig()
    {
        return DialectConfig.Builder()
            .ReservedWords(ReservedWords)
            .ReservedTopLevelWords(ReservedTopLevelWords)
            .ReservedTopLevelWordsNoIndent(ReservedTopLevelWordsNoIndent)
            .ReservedNewlineWords(ReservedNewlineWords)
            .StringTypes(
                new List<string>{
                        StringLiteral.DoubleQuote, StringLiteral.SingleQuote, StringLiteral.BackQuote})
            .OpenParens(new List<string> { "(", "[", "{" })
            .CloseParens(new List<string> { ")", "]", "}" })
            .NamedPlaceholderTypes(new List<string> { "$" })
            .LineCommentTypes(new List<string> { "#", "--" })
            .Operators(new List<string> { "==", "!=" })
            .Build();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="cfg"></param>
    /// <returns></returns>
    public N1qlFormatter(FormatConfig cfg) : base(cfg)
    {
    }
}